import type { Router, RouteRecord } from 'vue-router'
import { http } from '../../utils/http'
import { cloneDeep, isEqual } from 'lodash-es'
import { ref, markRaw } from 'vue'
import { useLoginAccountStoreWithOut } from '@/store/modules/login'
import { usePermissionStoreWithOut } from "@/store/modules/permission";
import { AppRouteRecordRaw } from '../types'
import { getModulesRouter } from '../routes';
import { rebuildMenu } from '..';

import { originalRouteRecords } from '.';

const loginAccountStore = useLoginAccountStoreWithOut()
const permissionStore = usePermissionStoreWithOut()

export async function createPermissionRouterGuardFromCache(router: Router) {
  let currentRoute = router.currentRoute.value

  if (currentRoute.name === 'Login') {
    return false;
  }

  let permissions = permissionStore.getPermissions;

  if (permissions === undefined || !permissions.routers) {
    return;
  }

  return refactorPermissionMetadata(router, permissions, true);
}

export async function createPermissionRouterGuard(router: Router, rebuild: boolean = false) {
  let currentRoute = router.currentRoute.value

  if (currentRoute.name === 'Login') {
    return false;
  }

  const permissions = await http?.request('get', '/api/permission/self', {
    headers: {
      'Authorization': `Bearer ${loginAccountStore.getToken}`
    }
  }).catch(_ => {    
    return false;
  });

  permissionStore.setPermissions(permissions)

  if (permissions === undefined || !permissions.routers) {
    return;
  }

  return refactorPermissionMetadata(router, permissions, rebuild);
}

function refactorPermissionMetadata(router: Router, permissions: any, rebuild: boolean = false) {
  let currentRoutes = router.getRoutes();

  originalRouteRecords.value?.forEach(r => {    
    let route = currentRoutes.find((x: any) => isEqual(x, r))

    if (route === undefined) {
      router.addRoute(r)
    }
  });

  let newModulesRouter = getModulesRouter()

  //console.log('身份是：', permissions.roles.join(' ')); 
  //console.log('初始化: ', newModulesRouter);

  if (permissions.routers.indexOf('#') != -1) {
    permissions.routers.forEach((e: string) => {
      if (e.indexOf('~') != -1) {      
        let path = e.slice(1)
        newModulesRouter.forEach((ie: AppRouteRecordRaw, idx: number) => {        
          if (path === ie.path) {
            router.removeRoute(ie.name as string)
            newModulesRouter = newModulesRouter.filter((item: AppRouteRecordRaw) => item !== ie)
          } else {
            if (ie.children != null && ie.children.length > 0) {
              ie.children.forEach(ce => {
                if (path === ce.path) {
                  router.removeRoute(ce.name as string)
                  let newChildren = newModulesRouter[idx]?.children?.filter((item: AppRouteRecordRaw) => item !== ce)

                  newModulesRouter[idx].children = newChildren
                }
              })
            }
          }
        });
      }
    });
    newModulesRouter = filterNonePermissionWithEmptyChildModulesRouter(router, newModulesRouter, permissions, true)
  } else {
    filterModuleRouter(router, newModulesRouter, permissions);
    newModulesRouter = filterNonePermissionWithEmptyChildModulesRouter(router, newModulesRouter, permissions, false)
  }

  if (rebuild) {
    rebuildMenu(newModulesRouter);
  }

  // console.log('原始数据：', getModulesRouter());
  // console.log('模块路由处理后：', newModulesRouter);
  // console.log('路由实例处理后：', router.getRoutes());
  // console.log('用户权限：', permissions.routers);

  return true;
}

function filterModuleRouter(router: Router, modulesRouter: AppRouteRecordRaw[], permissions: any): AppRouteRecordRaw[] {
  modulesRouter.forEach((e, i) => {
    if (!permissions.routers.includes(`${e.path}`) && (e.path !== '/error' && e.path != '/home')) {
      if (e.children == null || e.children?.length == 0) {
        router.removeRoute(e.name as string)
        router.removeRoute((e.path as string).substring(1))

        modulesRouter = modulesRouter.filter(item => item !== e)
        modulesRouter.forEach(re => {
          re.children = re.children?.filter(rec => rec != e);
        });
      }
      else {        
        modulesRouter = filterChildrenRouter(router, modulesRouter, e.children, permissions)

        if (e.children.length == 1 && e.redirect != e.children[0].path) {
          e.path = e.children[0].path
        }
      }
    }
  });

  return modulesRouter;
}

function filterChildrenRouter(router: Router, modulesRouter: AppRouteRecordRaw[], children: AppRouteRecordRaw[], permissions: any): AppRouteRecordRaw[] {
  if (children == null || children.length == 0) {
    return modulesRouter;
  }
    
  children.forEach(ie => {
    if (!permissions.routers.includes(`${ie.path}`) && (ie.path !== '/error' && ie.path != '/home')) {
      if (ie.children === undefined || ie.children === null || ie.children?.length == 0) {
        router.removeRoute(ie.name as string)
        router.removeRoute((ie.path as string).substring(1))

        modulesRouter = modulesRouter.filter(item => item !== ie)
        modulesRouter.forEach(re => {
          re.children = re.children?.filter(rec => rec != ie);
        });
      }
      else {
        modulesRouter = filterChildrenRouter(router, modulesRouter, ie.children, permissions)
      }
    }
  })

  return modulesRouter;
}

function filterNonePermissionWithEmptyChildModulesRouter(router: Router, modulesRouter: AppRouteRecordRaw[], permissions: any, isAdmin: boolean): AppRouteRecordRaw[] {
  modulesRouter.forEach(r => {
    let copy = permissions.routers.find((x: string) => x === r.path)

    if (copy === undefined && r.children?.length === 0) {
      modulesRouter = modulesRouter.filter(item => item != r);
    }
  });

  let removeRoutes: RouteRecord[] = [];
  let nowRoutes = router.getRoutes()

  if (isAdmin) {
    permissions.routers.forEach((e: string) => {
      if (e.indexOf('~') != -1) {
        let copy = nowRoutes.find(x => x.path === e.slice(1) || x.path.indexOf(`${e.slice(1)}/`) != -1)

        if (copy !== undefined) {
          removeRoutes.push(copy as RouteRecord)
        }
      }
    });
  } else {
    router.getRoutes().forEach(r => {
      permissions.routers.forEach((e: string) => {
        if (e.indexOf('~') != -1) {
          let copy = nowRoutes.find(x => x.path === e.slice(1) || x.path.indexOf(`${e.slice(1)}/`) != -1)

          if (copy !== undefined) {
            removeRoutes.push(copy as RouteRecord)
          }
        }
      });

      let copy = permissions.routers.find((x: string) => r.path.indexOf(x) != -1)
      if (copy === undefined && r.children?.length === 0 && r.meta.tag === 'perms') {
        removeRoutes.push(r)
      }
    });
  }

  removeRoutes.forEach(e => {
    router.removeRoute(e.name as string)
  })

  return modulesRouter;
}